import { Controller } from 'egg';
import NormalUserRule from '../validate/normalUserRule';
import EmailUserRule from '../validate/emailUserRule';
import PhoneUserRule from '../validate/phoneUserRule';
import jwt = require('jsonwebtoken');

// 定义常量枚举数据
const enum TypeEnum {
  Normal = 'normal',
  Email = 'email',
  Phone = 'phone'
}

export default class UserController extends Controller {
  // 测试
  // public async isLogin() {
  //   const { ctx } = this;
  //   // const user = ctx.session.user;
  //   // const { token } = ctx.query;
  //   // 获取请求头
  //   const token = ctx.get('authorization');
  //   // verify验证jwt 第一个参数为token,第二个参数为加密的密钥,还有一个参数是回调
  //   const decoded = jwt.verify(token, ctx.app.config.keys);
  //   try {
  //     ctx.success(decoded);
  //   } catch (e) {
  //     ctx.error(e.message);
  //   }
  // }
  // 登录处理
  public async login() {
    const { ctx } = this;
    try {
      // 1.调用校验方法校验数据和验证码
      this.validateUserInfo();
      const data = ctx.request.body;
      ctx.helper.verifyImageCode(data.captcha);
      // 2.将校验通过的数据进行查询登录处理
      const user = await ctx.service.user.getUser(data);
      // console.log(result, '111111111111111');
      // 判断该用户是否已经注销
      if (!user.userState) {
        return ctx.error(400, '该用户已经注销');
      }
      // ctx.session.user = user;
      const obj:any = {};
      obj.email = user.email;
      obj.phone = user.phone;
      obj.username = user.username;
      // 生成jwt token
      // 第一个参数是要生成的对象
      // 第二个参数是密钥 这里用config.keys就可以了
      const token = jwt.sign(obj, ctx.app.config.keys, { expiresIn: '7 days' });
      // user.token = token;
      // 不需要返回token字段给前端,后端自动把token设置到cookies中
      ctx.cookies.set('token', token, {
        path: '/',
        maxAge: 24 * 60 * 60 * 1000,
        // 🔔注意点: 这里不能设置为 true 不然前端无法获取到cookies
        httpOnly: false,
        signed: false, // 不需要签名
      });
      // 存储到session中,用来在中间件中做路由权限控制
      ctx.session.user = user;
      ctx.success(user);
    } catch (e) {
      if (e.errors) {
        ctx.error(400, e.errors);
      } else {
        ctx.error(400, e.message);
      }
    }
  }
  // 注册处理
  public async create() {
    const { ctx } = this;
    // console.log(ctx.request.body);
    try {
      // 1.调用校验方法校验数据和验证码
      this.validateUserInfo();
      this.validateUserCode();
      // 2.将校验通过的数据保存到数据库中
      const data = await ctx.service.user.createUser(ctx.request.body);
      // console.log('11111111', data);
      ctx.success(data); // 统一返回格式
    } catch (e) {
      if (e.errors) {
        ctx.error(400, e.errors);
      } else {
        ctx.error(400, e.message);
      }
    }
  }

  // 处理校验数据的逻辑
  private validateUserInfo() {
    const { ctx } = this;
    // 获取客户端的请求数据
    const data = ctx.request.body;
    // 获取参数中的类型
    const type = data.type;
    switch (type) {
      case TypeEnum.Normal:
        // 第一个参数是校验的规则,第二个是请求的参数
        // 校验数据的格式是否正确
        ctx.validate(NormalUserRule, data);
        break;
      case TypeEnum.Email:
        ctx.validate(EmailUserRule, data);
        break;
      case TypeEnum.Phone:
        ctx.validate(PhoneUserRule, data);
        break;
      default:
        throw new Error('注册类型不存在');
    }
  }
  // 处理校验图形验证码的逻辑
  private validateUserCode() {
    const { ctx } = this;
    // 获取客户端的请求数据
    const data = ctx.request.body;
    // 获取参数中的类型
    const type = data.type;
    switch (type) {
      case TypeEnum.Normal:
        // 第一个参数是校验的规则,第二个是请求的参数
        // 普通注册: 校验当前的验证码是否正确
        ctx.helper.verifyImageCode(data.captcha);
        break;
      case TypeEnum.Email:
        // 邮箱注册: 校验当前的验证码是否正确
        ctx.helper.verifyEmailCode(data.captcha);
        break;
      case TypeEnum.Phone:
        // 手机注册: 校验当前的验证码是否正确
        ctx.helper.verifyPhoneCode(data.captcha);
        break;
      default:
        throw new Error('注册类型不存在');
    }
  }
}
